package org.ohos.rajawali3d.examples.examples.interactive;

import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.service.WindowManager;
import ohos.app.Context;
import ohos.global.resource.RawFileEntry;
import ohos.global.resource.ResourceManager;
import org.ohos.rajawali3d.ResourceTable;
import org.ohos.rajawali3d.examples.examples.AExampleFragment;
import org.rajawali3d.Object3D;
import org.rajawali3d.animation.mesh.SkeletalAnimationObject3D;
import org.rajawali3d.animation.mesh.SkeletalAnimationSequence;
import org.rajawali3d.cameras.FirstPersonCamera;
import org.rajawali3d.lights.DirectionalLight;
import org.rajawali3d.loader.ParsingException;
import org.rajawali3d.loader.md5.LoaderMD5Anim;
import org.rajawali3d.loader.md5.LoaderMD5Mesh;
import org.rajawali3d.materials.Material;
import org.rajawali3d.materials.textures.ATexture;
import org.rajawali3d.materials.textures.Texture;
import org.rajawali3d.math.vector.Vector3;
import org.rajawali3d.primitives.Sphere;
import org.rajawali3d.renderer.ISurfaceRenderer;

/**
 * @author Jared Woolston (jwoolston@idealcorp.com)
 */
public class FirstPersonCameraFragment extends AExampleFragment {

    private Button mMoveForward;
    private Button mMoveRight;
    private Button mMoveUp;

    @Override
    public Component onCreateView(LayoutScatter inflater, ComponentContainer container, Intent savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        DirectionalLayout ll = new DirectionalLayout(getContext());
        ComponentContainer.LayoutConfig lc = ll.getLayoutConfig();
        lc.width = DirectionalLayout.LayoutConfig.MATCH_PARENT;
        lc.height = DirectionalLayout.LayoutConfig.MATCH_PARENT;
        ll.setOrientation(DirectionalLayout.HORIZONTAL);
        ll.setAlignment(LayoutAlignment.BOTTOM);

        mMoveForward = new Button(getContext());
        mMoveForward.setText("Forward");
        mMoveForward.setTextColor(Color.WHITE);
        mMoveForward.setTextSize(60);
        mMoveForward.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                ((FPSRenderer) mRenderer).onClickItem(component);
            }
        });
        mMoveForward.setMarginsTopAndBottom(0, 10);
        mMoveForward.setMarginsLeftAndRight(10, 10);
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(0xFFADADAD));
        mMoveForward.setBackground(shapeElement);
        ll.addComponent(mMoveForward);
        ComponentContainer.LayoutConfig layoutConfig = mMoveForward.getLayoutConfig();
        layoutConfig.width = 260;
        layoutConfig.height = DirectionalLayout.LayoutConfig.MATCH_CONTENT;


        mMoveRight = new Button(getContext());
        mMoveRight.setText("Right");
        mMoveRight.setTextColor(Color.WHITE);
        mMoveRight.setTextSize(60);
        mMoveRight.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                ((FPSRenderer) mRenderer).onClickItem(component);
            }
        });
        mMoveRight.setBackground(shapeElement);
        mMoveRight.setMarginsTopAndBottom(0, 10);
        mMoveRight.setMarginsLeftAndRight(10, 10);
        ComponentContainer.LayoutConfig layoutConfig2 = mMoveRight.getLayoutConfig();
        layoutConfig2.width = 260;//DirectionalLayout.LayoutConfig.MATCH_CONTENT;
        layoutConfig2.height = DirectionalLayout.LayoutConfig.MATCH_CONTENT;
        ll.addComponent(mMoveRight);

        mMoveUp = new Button(getContext());
        mMoveUp.setText("Up");
        mMoveUp.setTextColor(Color.WHITE);
        mMoveUp.setTextSize(60);
        mMoveUp.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                ((FPSRenderer) mRenderer).onClickItem(component);
            }
        });
        mMoveUp.setBackground(shapeElement);
        mMoveUp.setMarginsTopAndBottom(0, 10);
        mMoveUp.setMarginsLeftAndRight(10, 10);
        ComponentContainer.LayoutConfig layoutConfig3 = mMoveUp.getLayoutConfig();
        layoutConfig3.width = 260;//DirectionalLayout.LayoutConfig.MATCH_CONTENT;
        layoutConfig3.height = DirectionalLayout.LayoutConfig.MATCH_CONTENT;
        ll.addComponent(mMoveUp);

        mLayout.addComponent(ll);

        ll.setTotalWeight(1);
        mLayout.moveChildToFront(ll);
        mRenderSurface.setTransparent(false);
        WindowManager.getInstance().getTopWindow().get().setTransparent(true);

        return mLayout;
    }

    @Override
    public ISurfaceRenderer createRenderer() {
        mRenderer = new FPSRenderer(getContext(), this);
        return mRenderer;
    }

    private class FPSRenderer extends AExampleRenderer {

        private DirectionalLight mLight;
        private Object3D mSphere;

        private SkeletalAnimationObject3D mPerson;

        public FPSRenderer(Context context, AExampleFragment fragment) {
            super(context, fragment);
        }

        @Override
        protected void initScene() {
            mLight = new DirectionalLight(0, -0.2f, -1.0f); // set the direction
            mLight.setColor(1.0f, 1.0f, 1.0f);
            mLight.setPower(2);

            getCurrentScene().addLight(mLight);

            // Load the person model
            try {
                ResourceManager resManager = mContext.getResourceManager();
                RawFileEntry rawFileEntry = resManager.getRawFileEntry("resources/rawfile/boblampclean_mesh.md5mesh");
                final LoaderMD5Mesh meshParser = new LoaderMD5Mesh(this, rawFileEntry);
                meshParser.parse(mContext);
                RawFileEntry rawFileEntry2 = resManager.getRawFileEntry("resources/rawfile/boblampclean_anim.md5anim");
                final LoaderMD5Anim animParser = new LoaderMD5Anim("attack2", this, rawFileEntry2);
                animParser.parse(mContext);

                SkeletalAnimationSequence sequence = (SkeletalAnimationSequence) animParser.getParsedAnimationSequence();

                mPerson = (SkeletalAnimationObject3D) meshParser.getParsedAnimationObject();
                mPerson.setAnimationSequence(sequence);
                mPerson.setScale(.04f);
                mPerson.enableLookAt();
                mPerson.setLookAt(Vector3.ZERO);
                mPerson.setPosition(0, 0, 6);

                mPerson.play();

                getCurrentScene().addChild(mPerson);
            } catch (ParsingException e) {
                e.printStackTrace();
            }

            try {
                Material material = new Material();
                material.addTexture(new Texture("earthColors",
                        ResourceTable.Media_earthtruecolor_nasa_big));
                material.setColorInfluence(0);
                mSphere = new Sphere(1, 24, 24);
                mSphere.setPosition(0, 0, -5.0);
                mSphere.setMaterial(material);
                mSphere.enableLookAt();
                mSphere.setLookAt(10.0, 10.0, 10.0);
                getCurrentScene().addChild(mSphere);
            } catch (ATexture.TextureException e) {
                e.printStackTrace();
            }

            final FirstPersonCamera camera = new FirstPersonCamera(new Vector3(0.0, 2.25, 0.0), mPerson);
            camera.setNearPlane(0.4);
            camera.setCameraYaw(180.0);
            getCurrentScene().addAndSwitchCamera(camera);
        }

        public void onClickItem(Component v) {
            if (mSceneInitialized) {
                if (v.equals(mMoveForward)) {
                    mPerson.moveForward(0.25);
                } else if (v.equals(mMoveRight)) {
                    mPerson.moveRight(0.25);
                } else if (v.equals(mMoveUp)) {
                    mPerson.moveUp(0.25);
                }
            }
        }
    }
}
